home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / contribu / tcpdump-.6 / tcpdump- / smb.diffs < prev    next >
Encoding:
Text File  |  1995-06-30  |  58.5 KB  |  1,982 lines

  1. diff -u --new-file orig/Makefile ./Makefile
  2. --- orig/Makefile    Tue Jun 20 23:18:38 1995
  3. +++ ./Makefile    Tue Jun 20 23:06:49 1995
  4. @@ -101,7 +101,7 @@
  5.      print-snmp.c print-ntp.c print-null.c print-egp.c print-ospf.c \
  6.      print-fddi.c print-llc.c print-sunrpc.c \
  7.      print-wb.c print-decnet.c print-isoclns.c print-ipx.c \
  8. -    util.c bpf_dump.c parsenfsfh.c
  9. +    util.c bpf_dump.c parsenfsfh.c print-smb.c smbutil.c
  10.  GEN =    version.c
  11.  
  12.  SRC =    $(CSRC) $(GEN)
  13. diff -u --new-file orig/Makefile.in ./Makefile.in
  14. --- orig/Makefile.in    Tue Jun 20 23:00:00 1995
  15. +++ ./Makefile.in    Tue Jun 20 23:02:08 1995
  16. @@ -101,7 +101,7 @@
  17.      print-snmp.c print-ntp.c print-null.c print-egp.c print-ospf.c \
  18.      print-fddi.c print-llc.c print-sunrpc.c \
  19.      print-wb.c print-decnet.c print-isoclns.c print-ipx.c \
  20. -    util.c bpf_dump.c parsenfsfh.c
  21. +    util.c bpf_dump.c parsenfsfh.c print-smb.c smbutil.c
  22.  GEN =    version.c
  23.  
  24.  SRC =    $(CSRC) $(GEN)
  25. diff -u --new-file orig/README.smb ./README.smb
  26. --- orig/README.smb    Thu Jan  1 10:00:00 1970
  27. +++ ./README.smb    Thu Jun 22 15:47:23 1995
  28. @@ -0,0 +1,56 @@
  29. +This is set of patches to tcpdump-3 that gives it the ability to
  30. +interpret NBT and SMB packets in a fair bit of detail.
  31. +
  32. +The patches were actually made against tcpdump-3.0.3 as distributed in
  33. +the debian linux distribution. They should, however, apply fairly
  34. +easily to other tcpdump-3 distributions.
  35. +
  36. +The binary of tcpdump supplied with this package was built for Linux
  37. +using libraries 4.6.27 and kernel 1.3.3 (although the exact version
  38. +numbers shouldn't matter too much).
  39. +
  40. +Please send any feedback to Andrew.Tridgell@anu.edu.au
  41. +
  42. +Usage:
  43. +
  44. +To capture all SMB packets going to or from host "fred" try this:
  45. +
  46. +tcpdump -i eth0 -s 1500 port 139 host fred
  47. +
  48. +If you want name resolution or browse packets then try ports 137 and
  49. +138 respectively.
  50. +
  51. +change log:
  52. +    0.2: added name server and browse stuff
  53. +    0.3: added IPX and Netbeui support
  54. +
  55. +Example Output:
  56. +
  57. +Here is a sample of a capture of a "SMBsearch" directory search. If
  58. +you don't get output that looks like this then you have patched
  59. +tcpdump incorrectly.
  60. +
  61. +NBT Session Packet
  62. +Flags=0x0
  63. +Length=57
  64. +
  65. +SMB PACKET: SMBsearch (REQUEST)
  66. +SMB Command   =  0x81
  67. +Error class   =  0x0
  68. +Error code    =  0
  69. +Flags1        =  0x8
  70. +Flags2        =  0x3
  71. +Tree ID       =  2048
  72. +Proc ID       =  11787
  73. +UID           =  2048
  74. +MID           =  11887
  75. +Word Count    =  2
  76. +smbvwv[]=
  77. +Count=98
  78. +Attrib=HIDDEN SYSTEM DIR 
  79. +smbbuf[]=
  80. +Path=\????????.???
  81. +BlkType=0x5
  82. +BlkLen=0
  83. +
  84. +
  85. diff -u --new-file orig/dist ./dist
  86. --- orig/dist    Thu Jan  1 10:00:00 1970
  87. +++ ./dist    Thu Jun 22 11:15:29 1995
  88. @@ -0,0 +1,8 @@
  89. +#!/bin/sh
  90. +VERSION=$1
  91. +rm -f *.diffs *out*
  92. +diff -u --new-file orig/ . | egrep -v '^Binary' > /tmp/smb.diffs
  93. +mv /tmp/smb.diffs .
  94. +tar -czvf tcpdump-smb-$VERSION.tar.gz README.smb smb.diffs tcpdump
  95. +
  96. +
  97. Common subdirectories: orig/libpcap and ./libpcap
  98. Common subdirectories: orig/orig and ./orig
  99. diff -u --new-file orig/print-llc.c ./print-llc.c
  100. --- orig/print-llc.c    Tue Jun 20 23:00:00 1995
  101. +++ ./print-llc.c    Sat Jun 24 03:42:10 1995
  102. @@ -83,10 +83,9 @@
  103.          ipx_print(p, length);
  104.          return (1);
  105.      }
  106. -#ifdef notyet
  107. -    else if (p[0] == 0xf0 && p[1] == 0xf0)
  108. -        netbios_print(p, length);
  109. -#endif
  110. +    else if (p[0] == 0xf0 && p[1] == 0xf0) {
  111. +      netbeui_print(p+2,p+min(caplen,length));
  112. +    }
  113.      if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS
  114.          && llc.llcui == LLC_UI) {
  115.          isoclns_print(p + 3, length - 3, caplen - 3, esrc, edst);
  116. @@ -161,6 +160,10 @@
  117.              caplen -= 3;
  118.              }
  119.          }
  120. +
  121. +        if (!strcmp(m,"ui") && f=='C')
  122. +          ipx_netbios_print(p,p+min(caplen,length));
  123. +
  124.      } else {
  125.          char f;
  126.          llc.llcis = ntohs(llc.llcis);
  127. @@ -189,8 +192,5 @@
  128.          caplen -= 4;
  129.      }
  130.      (void)printf(" len=%d", length);
  131. -    if (caplen > 0) {
  132. -        default_print_unaligned(p, caplen);
  133. -    }
  134.      return(1);
  135.  }
  136. diff -u --new-file orig/print-smb.c ./print-smb.c
  137. --- orig/print-smb.c    Thu Jan  1 10:00:00 1970
  138. +++ ./print-smb.c    Thu Jun 29 14:39:41 1995
  139. @@ -0,0 +1,979 @@
  140. +/* 
  141. +   Copyright (C) Andrew Tridgell 1995
  142. +   
  143. +   This program is free software; you can redistribute it and/or modify
  144. +   it under the terms of the GNU General Public License as published by
  145. +   the Free Software Foundation; either version 2 of the License, or
  146. +   (at your option) any later version.
  147. +   
  148. +   This program is distributed in the hope that it will be useful,
  149. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  150. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  151. +   GNU General Public License for more details.
  152. +   
  153. +   You should have received a copy of the GNU General Public License
  154. +   along with this program; if not, write to the Free Software
  155. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  156. +*/
  157. +
  158. +#include <stdio.h>
  159. +#include <sys/types.h>
  160. +
  161. +#include "smb.h"
  162. +
  163. +static int request=0;
  164. +
  165. +uchar *startbuf=NULL;
  166. +
  167. +struct smbdescript
  168. +{
  169. +  char *req_f1;
  170. +  char *req_f2;
  171. +  char *rep_f1;
  172. +  char *rep_f2;
  173. +  void (*fn)();
  174. +};
  175. +
  176. +struct smbfns
  177. +{
  178. +  int id;
  179. +  char *name;
  180. +  int flags;
  181. +  struct smbdescript descript;
  182. +};
  183. +
  184. +#define DEFDESCRIPT  {NULL,NULL,NULL,NULL,NULL}
  185. +
  186. +#define FLG_CHAIN (1<<0)
  187. +
  188. +static struct smbfns *smbfind(int id,struct smbfns *list)
  189. +{
  190. +  int sindex;
  191. +
  192. +  for (sindex=0;list[sindex].name;sindex++) 
  193. +    if (list[sindex].id == id) return(&list[sindex]);
  194. +
  195. +  return(&list[0]);
  196. +}
  197. +
  198. +static void trans2_findfirst(uchar *param,uchar *data,int pcnt,int dcnt)
  199. +{
  200. +  char *fmt;
  201. +
  202. +  if (request) {
  203. +    fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP5]\nFile=[S]\n";
  204. +  } else {
  205. +    fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n";
  206. +  }
  207. +
  208. +  fdata(param,fmt,param+pcnt);
  209. +  if (dcnt) {
  210. +    printf("data:\n");
  211. +    print_data(data,dcnt);
  212. +  }
  213. +}
  214. +
  215. +static void trans2_qfsinfo(uchar *param,uchar *data,int pcnt,int dcnt)
  216. +{
  217. +  static int level=0;
  218. +  char *fmt="";
  219. +
  220. +  if (request) {
  221. +    level = SVAL(param,0);
  222. +    fmt = "InfoLevel=[d]\n";
  223. +    fdata(param,fmt,param+pcnt);
  224. +  } else {
  225. +    switch (level) {
  226. +    case 1:
  227. +      fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n";
  228. +      break;
  229. +    case 2:
  230. +      fmt = "CreationTime=[T2]VolNameLength=[B]\nVolumeLabel=[s12]\n";
  231. +      break;
  232. +    case 0x105:
  233. +      fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[D]\nVolume=[S]\n";
  234. +      break;
  235. +    default:
  236. +      fmt = "UnknownLevel\n";
  237. +    }
  238. +    fdata(data,fmt,data+dcnt);
  239. +  }
  240. +  if (dcnt) {
  241. +    printf("data:\n");
  242. +    print_data(data,dcnt);
  243. +  }
  244. +}
  245. +
  246. +struct smbfns trans2_fns[] = {
  247. +{0,"TRANSACT2_OPEN",0,
  248. +   {"Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[D]\nRes=([w,w,w,w,w])\nPath=[S]",NULL,
  249. +    "Handle=[d]\nAttrib=[A]\nTime=[T2]\nSize=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[d]\n|EALength=[d]\n",NULL,NULL}},
  250. +
  251. +{1,"TRANSACT2_FINDFIRST",0,
  252. +   {NULL,NULL,NULL,NULL,trans2_findfirst}},
  253. +
  254. +{2,"TRANSACT2_FINDNEXT",0,DEFDESCRIPT},
  255. +
  256. +{3,"TRANSACT2_QFSINFO",0,
  257. +   {NULL,NULL,NULL,NULL,trans2_qfsinfo}},
  258. +
  259. +{4,"TRANSACT2_SETFSINFO",0,DEFDESCRIPT},
  260. +{5,"TRANSACT2_QPATHINFO",0,DEFDESCRIPT},
  261. +{6,"TRANSACT2_SETPATHINFO",0,DEFDESCRIPT},
  262. +{7,"TRANSACT2_QFILEINFO",0,DEFDESCRIPT},
  263. +{8,"TRANSACT2_SETFILEINFO",0,DEFDESCRIPT},
  264. +{9,"TRANSACT2_FSCTL",0,DEFDESCRIPT},
  265. +{10,"TRANSACT2_IOCTL",0,DEFDESCRIPT},
  266. +{11,"TRANSACT2_FINDNOTIFYFIRST",0,DEFDESCRIPT},
  267. +{12,"TRANSACT2_FINDNOTIFYNEXT",0,DEFDESCRIPT},
  268. +{13,"TRANSACT2_MKDIR",0,DEFDESCRIPT},
  269. +{-1,NULL,0,DEFDESCRIPT}};
  270. +
  271. +
  272. +static void print_trans2(uchar *words,uchar *dat,uchar *buf,uchar *maxbuf)
  273. +{
  274. +  static struct smbfns *fn = &trans2_fns[0];
  275. +  uchar *data,*param;
  276. +  uchar *f1=NULL,*f2=NULL;
  277. +  int pcnt,dcnt;
  278. +
  279. +  if (request) {
  280. +    fn = smbfind(SVAL(words+1,14*2),trans2_fns);
  281. +    data = buf+SVAL(words+1,12*2);
  282. +    param = buf+SVAL(words+1,10*2);
  283. +    pcnt = SVAL(words+1,9*2);
  284. +    dcnt = SVAL(words+1,11*2);
  285. +  } else {
  286. +    data = buf+SVAL(words+1,7*2);
  287. +    param = buf+SVAL(words+1,4*2);
  288. +    pcnt = SVAL(words+1,3*2);
  289. +    dcnt = SVAL(words+1,6*2);
  290. +  }
  291. +
  292. +  printf("%s param_length=%d data_length=%d\n",
  293. +     fn->name,pcnt,dcnt);
  294. +
  295. +  if (request) {
  296. +    if (CVAL(words,0) == 8) {
  297. +      fdata(words+1,"Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n",maxbuf);
  298. +      return;        
  299. +    } else {
  300. +      fdata(words+1,"TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[d]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[d]\n",words+1+14*2);
  301. +      fdata(data+1,"TransactionName=[S]\n%",maxbuf);
  302. +    }
  303. +    f1 = fn->descript.req_f1;
  304. +    f2 = fn->descript.req_f2;
  305. +  } else {
  306. +    if (CVAL(words,0) == 0) {
  307. +      printf("Trans2Interim\n");
  308. +      return;
  309. +    } else {
  310. +      fdata(words+1,"TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[d]\n",words+1+10*2);
  311. +    }
  312. +    f1 = fn->descript.rep_f1;
  313. +    f2 = fn->descript.rep_f2;
  314. +  }
  315. +
  316. +  if (fn->descript.fn) {
  317. +    fn->descript.fn(param,data,pcnt,dcnt);
  318. +  } else {
  319. +    fdata(param,f1?f1:(uchar*)"Paramaters=\n",param+pcnt);
  320. +    fdata(data,f2?f2:(uchar*)"Data=\n",data+dcnt);      
  321. +  }
  322. +}
  323. +
  324. +
  325. +static void print_browse(uchar *param,int paramlen,uchar *data,int datalen)
  326. +{
  327. +  uchar *maxbuf = data + datalen;
  328. +  int command = CVAL(data,0);
  329. +
  330. +  fdata(param,"BROWSE PACKET\n|Param ",param+paramlen);
  331. +
  332. +  switch (command) {
  333. +  case 0xF:
  334. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",maxbuf);
  335. +    break;
  336. +    
  337. +  case 0x1:
  338. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",maxbuf);
  339. +    break;
  340. +    
  341. +  case 0x2:
  342. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n",maxbuf);
  343. +    break;
  344. +    
  345. +  case 0xc:
  346. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n",maxbuf);
  347. +    break;
  348. +
  349. +  case 0x8:
  350. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W,W)]\nServerName=[S]\n",maxbuf);
  351. +    break;
  352. +    
  353. +  case 0xb:
  354. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n",maxbuf);
  355. +    break;
  356. +    
  357. +  case 0x9:
  358. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken?=[B]\n",maxbuf);
  359. +    break;
  360. +    
  361. +  case 0xa:
  362. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken?=[B]*Name=[S]\n",maxbuf);
  363. +    break;
  364. +    
  365. +  case 0xd:
  366. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n",maxbuf);
  367. +    break;
  368. +    
  369. +  case 0xe:
  370. +    data = fdata(data,"BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n",maxbuf);
  371. +    break;
  372. +    
  373. +  default:
  374. +    data = fdata(data,"Unknown Browser Frame ",maxbuf);
  375. +    break;
  376. +  }
  377. +}
  378. +
  379. +
  380. +static void print_ipc(uchar *param,int paramlen,uchar *data,int datalen)
  381. +{
  382. +  int command = SVAL(param,0);
  383. +  if (paramlen)
  384. +    fdata(param,"Command=[w]\nStr1=[S]\nStr2=[S]\n",param+paramlen);
  385. +  if (datalen)
  386. +    fdata(data,"IPC ",data+datalen);
  387. +}
  388. +
  389. +
  390. +static void print_trans(uchar *words,uchar *data1,uchar *buf,uchar *maxbuf)
  391. +{
  392. +  uchar *f1,*f2,*f3,*f4;
  393. +  uchar *data,*param;
  394. +  int datalen,paramlen;
  395. +  int buflen = SVAL(data1,0);
  396. +
  397. +  if (request) {
  398. +    paramlen = SVAL(words+1,9*2);
  399. +    param = buf + SVAL(words+1,10*2);
  400. +    datalen = SVAL(words+1,11*2);
  401. +    data = buf + SVAL(words+1,12*2);
  402. +    f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nMaxParmCnt=[d] \nMaxDataCnt=[d]\nMaxSCnt=[d] \nTransFlags=[w] \nRes1=[w] \nRes2=[w] \nRes3=[w]\nParamCnt=[d] \nParamOff=[d] \nDataCnt=[d] \nDataOff=[d] \nSUCnt=[d]\n";
  403. +    f2 = "|Name=[S]\n";
  404. +    f3 = "|Param ";
  405. +    f4 = "|Data ";
  406. +  } else {
  407. +    paramlen = SVAL(words+1,3*2);
  408. +    param = buf + SVAL(words+1,4*2);
  409. +    datalen = SVAL(words+1,6*2);
  410. +    data = buf + SVAL(words+1,7*2);
  411. +    f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nRes1=[d]\nParamCnt=[d] \nParamOff=[d] \nRes2=[d] \nDataCnt=[d] \nDataOff=[d] \nRes3=[d]\nLsetup=[d]\n";
  412. +    f2 = "|Unknown ";
  413. +    f3 = "|Param ";
  414. +    f4 = "|Data ";
  415. +  }
  416. +
  417. +  fdata(words+1,f1,MIN(words+1+2*CVAL(words,0),maxbuf));
  418. +  fdata(data1+2,f2,maxbuf - (paramlen + datalen));
  419. +
  420. +  if (!strcmp(data1+2,"\\MAILSLOT\\BROWSE")) {
  421. +    print_browse(param,paramlen,data,datalen);
  422. +    return;
  423. +  }
  424. +
  425. +  if (!strcmp(data1+2,"\\PIPE\\LANMAN")) {
  426. +    print_ipc(param,paramlen,data,datalen);
  427. +    return;
  428. +  }
  429. +
  430. +  if (paramlen) fdata(param,f3,MIN(param+paramlen,maxbuf));
  431. +  if (datalen) fdata(data,f4,MIN(data+datalen,maxbuf));
  432. +}
  433. +
  434. +
  435. +
  436. +void print_negprot(uchar *words,uchar *data,uchar *buf,uchar *maxbuf)
  437. +{
  438. +  uchar *f1=NULL,*f2=NULL;
  439. +
  440. +  if (request) {
  441. +    f2 = "*|Dialect=[Z]\n";
  442. +  } else {
  443. +    if (CVAL(words,0) == 1) {
  444. +      f1 = "Core Protocol\nDialectIndex=[d]";
  445. +    } else if (CVAL(words,0) == 17) {
  446. +      f1 = "NT1 Protocol\nDialectIndex=[d]\nSecMode=[B]\nMaxMux=[d]\nNumVcs=[d]\nMaxBuffer=[D]\nRawSize=[D]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[d]\nCryptKey=";
  447. +    } else if (CVAL(words,0) == 13) {
  448. +      f1 = "Coreplus/Lanman1/Lanman2 Protocol\nDialectIndex=[d]\nSecMode=[w]\nMaxXMit=[d]\nMaxMux=[d]\nMaxVcs=[d]\nBlkMode=[w]\nSessionKey=[W]\nServerTime=[T1]TimeZone=[d]\nRes=[W]\nCryptKey=";
  449. +    }
  450. +  }
  451. +
  452. +  if (f1) 
  453. +    fdata(words+1,f1,MIN(words + 1 + CVAL(words,0)*2,maxbuf));
  454. +  else
  455. +    print_data(words+1,MIN(CVAL(words,0)*2,PTR_DIFF(maxbuf,words+1)));
  456. +  
  457. +  if (f2) 
  458. +    fdata(data+2,f2,MIN(data + 2 + SVAL(data,0),maxbuf));
  459. +  else
  460. +    print_data(data+2,MIN(SVAL(data,0),PTR_DIFF(maxbuf,data+2)));
  461. +    
  462. +}
  463. +
  464. +void print_sesssetup(uchar *words,uchar *data,uchar *buf,uchar *maxbuf)
  465. +{
  466. +  int wcnt = CVAL(words,0);
  467. +  uchar *f1=NULL,*f2=NULL;
  468. +
  469. +  if (request) {
  470. +    if (wcnt==10) {
  471. +      f1 = "Com2=[w]\nOff2=[d]\nBufSize=[d]\nMpxMax=[d]\nVcNum=[d]\nSessionKey=[W]\nPassLen=[d]\nCryptLen=[d]\nCryptOff=[d]\nPass&Name=\n";
  472. +    } else {
  473. +      f1 = "Com2=[B]\nRes1=[B]\nOff2=[d]\nMaxBuffer=[d]\nMaxMpx=[d]\nVcNumber=[d]\nSessionKey=[W]\nCaseInsensitivePasswordLength=[d]\nCaseSensitivePasswordLength=[d]\nRes=[W]\nCapabilities=[W]\nPass1&Pass2&Account&Domain&OS&LanMan=\n";
  474. +    }
  475. +  } else {
  476. +    if (CVAL(words,0) == 3) {
  477. +      f1 = "Com2=[w]\nOff2=[d]\nAction=[w]\n";
  478. +    } else if (CVAL(words,0) == 13) {
  479. +      f1 = "Com2=[B]\nRes=[B]\nOff2=[d]\nAction=[w]\n";
  480. +      f2 = "NativeOS=[S]\nNativeLanMan=[S]\nPrimaryDomain=[S]\n";
  481. +    }
  482. +  }
  483. +
  484. +  if (f1) 
  485. +    fdata(words+1,f1,MIN(words + 1 + CVAL(words,0)*2,maxbuf));
  486. +  else
  487. +    print_data(words+1,MIN(CVAL(words,0)*2,PTR_DIFF(maxbuf,words+1)));
  488. +  
  489. +  if (f2) 
  490. +    fdata(data+2,f2,MIN(data + 2 + SVAL(data,0),maxbuf));
  491. +  else
  492. +    print_data(data+2,MIN(SVAL(data,0),PTR_DIFF(maxbuf,data+2))); 
  493. +}
  494. +
  495. +
  496. +static struct smbfns smb_fns[] = 
  497. +{
  498. +{-1,"SMBunknown",0,DEFDESCRIPT},
  499. +
  500. +{SMBtcon,"SMBtcon",0,
  501. +   {NULL,"Path=[Z]\nPassword=[Z]\nDevice=[Z]\n",
  502. +    "MaxXmit=[d]\nTreeId=[d]\n",NULL,
  503. +    NULL}},
  504. +
  505. +
  506. +{SMBtdis,"SMBtdis",0,DEFDESCRIPT},
  507. +{SMBexit,"SMBexit",0,DEFDESCRIPT},
  508. +{SMBioctl,"SMBioctl",0,DEFDESCRIPT},
  509. +
  510. +{SMBecho,"SMBecho",0,
  511. +   {"ReverbCount=[d]\n",NULL,
  512. +    "SequenceNum=[d]\n",NULL,
  513. +    NULL}},
  514. +
  515. +{SMBulogoffX, "SMBulogoffX",FLG_CHAIN,DEFDESCRIPT},
  516. +
  517. +{SMBgetatr,"SMBgetatr",0,
  518. +   {NULL,"Path=[Z]\n",
  519. +    "Attribute=[A]\nTime=[T2]Size=[D]\nRes=([w,w,w,w,w])\n",NULL,
  520. +    NULL}},
  521. +
  522. +{SMBsetatr,"SMBsetatr",0,
  523. +   {"Attribute=[A]\nTime=[T2]Res=([w,w,w,w,w])\n","Path=[Z]\n",
  524. +    NULL,NULL,NULL}},
  525. +
  526. +{SMBchkpth,"SMBchkpth",0,
  527. +   {NULL,"Path=[Z]\n",NULL,NULL,NULL}},
  528. +
  529. +{SMBsearch,"SMBsearch",0,
  530. +{"Count=[d]\nAttrib=[A]\n","Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\n",
  531. +"Count=[d]\n","BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",NULL}},
  532. +
  533. +
  534. +{SMBopen,"SMBopen",0,
  535. +   {"Mode=[w]\nAttribute=[A]\n","Path=[Z]\n",
  536. +    "Handle=[d]\nOAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\n",NULL,
  537. +    NULL}},
  538. +
  539. +{SMBcreate,"SMBcreate",0,
  540. +   {"Attrib=[A]\nTime=[T2]","Path=[Z]\n",
  541. +    "Handle=[d]\n",NULL,
  542. +    NULL}},
  543. +
  544. +{SMBmknew,"SMBmknew",0,
  545. +   {"Attrib=[A]\nTime=[T2]","Path=[Z]\n",
  546. +    "Handle=[d]\n",NULL,
  547. +    NULL}},
  548. +
  549. +{SMBunlink,"SMBunlink",0,
  550. +   {"Attrib=[A]\n","Path=[Z]\n",NULL,NULL,NULL}},
  551. +
  552. +{SMBread,"SMBread",0,
  553. +   {"Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n",NULL,
  554. +    "Count=[d]\nRes=([w,w,w,w])\n",NULL,NULL}},
  555. +
  556. +{SMBwrite,"SMBwrite",0,
  557. +   {"Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n",NULL,
  558. +    "Count=[d]\n",NULL,NULL}},
  559. +
  560. +{SMBclose,"SMBclose",0,
  561. +   {"Handle=[d]\nTime=[T2]",NULL,NULL,NULL,NULL}},
  562. +
  563. +{SMBmkdir,"SMBmkdir",0,
  564. +   {NULL,"Path=[Z]\n",NULL,NULL,NULL}},
  565. +
  566. +{SMBrmdir,"SMBrmdir",0,
  567. +   {NULL,"Path=[Z]\n",NULL,NULL,NULL}},
  568. +
  569. +{SMBdskattr,"SMBdskattr",0,
  570. +{NULL,NULL,
  571. +"TotalUnits=[d]\nBlocksPerUnit=[d]\nBlockSize=[d]\nFreeUnits=[d]\nMedia=[w]\n",
  572. +NULL,NULL}},
  573. +
  574. +{SMBmv,"SMBmv",0,
  575. +   {"Attrib=[A]\n","OldPath=[Z]\nNewPath=[Z]\n",NULL,NULL,NULL}},
  576. +
  577. +/* this is a Pathworks specific call, allowing the 
  578. +   changing of the root path */
  579. +{pSETDIR,"SMBsetdir",0,
  580. +   {NULL,"Path=[Z]\n",NULL,NULL,NULL}},
  581. +
  582. +{SMBlseek,"SMBlseek",0,
  583. +   {"Handle=[d]\nMode=[w]\nOffset=[D]\n","Offset=[D]\n",NULL,NULL}},
  584. +
  585. +{SMBflush,"SMBflush",0,
  586. +   {"Handle=[d]\n",NULL,NULL,NULL,NULL}},
  587. +
  588. +{SMBsplopen,"SMBsplopen",0,
  589. +   {"SetupLen=[d]\nMode=[w]\n","Ident=[Z]\n","Handle=[d]\n",NULL,NULL}},
  590. +
  591. +{SMBsplclose,"SMBsplclose",0,
  592. +   {"Handle=[d]\n",NULL,NULL,NULL,NULL}},
  593. +
  594. +{SMBsplretq,"SMBsplretq",0,
  595. +   {"MaxCount=[d]\nStartIndex=[d]\n",NULL,
  596. +    "Count=[d]\nIndex=[d]\n",
  597. +    "*Time=[T2]Status=[B]\nJobID=[d]\nSize=[D]\nRes=[B]Name=[s16]\n",
  598. +    NULL}},
  599. +
  600. +{SMBsplwr,"SMBsplwr",0,
  601. +   {"Handle=[d]\n",NULL,NULL,NULL,NULL}},
  602. +
  603. +{SMBlock,"SMBlock",0,
  604. +   {"Handle=[d]\nCount=[D]\nOffset=[D]\n",NULL,NULL,NULL,NULL}},
  605. +
  606. +{SMBunlock,"SMBunlock",0,
  607. +   {"Handle=[d]\nCount=[D]\nOffset=[D]\n",NULL,NULL,NULL,NULL}},
  608. +
  609. +/* CORE+ PROTOCOL FOLLOWS */
  610. +
  611. +{SMBreadbraw,"SMBreadbraw",0,
  612. +{"Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[d]\n",
  613. + NULL,NULL,NULL,NULL}},
  614. +
  615. +{SMBwritebraw,"SMBwritebraw",0,
  616. +{"Handle=[d]\nTotalCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[d]\nDataOff=[d]\n",
  617. +NULL,"WriteRawAck",NULL,NULL}},
  618. +
  619. +{SMBwritec,"SMBwritec",0,
  620. +   {NULL,NULL,"Count=[d]\n",NULL,NULL}},
  621. +
  622. +{SMBwriteclose,"SMBwriteclose",0,
  623. +   {"Handle=[d]\nCount=[d]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])",NULL,
  624. +    "Count=[d]\n",NULL,NULL}},
  625. +
  626. +{SMBlockread,"SMBlockread",0,
  627. +   {"Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n",NULL,
  628. +    "Count=[d]\nRes=([w,w,w,w])\n",NULL,NULL}},
  629. +
  630. +{SMBwriteunlock,"SMBwriteunlock",0,
  631. +   {"Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n",NULL,
  632. +    "Count=[d]\n",NULL,NULL}},
  633. +
  634. +{SMBreadBmpx,"SMBreadBmpx",0,
  635. +{"Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[w]\n",
  636. +NULL,
  637. +"Offset=[D]\nTotCount=[d]\nRemaining=[d]\nRes=([w,w])\nDataSize=[d]\nDataOff=[d]\n",
  638. +NULL,NULL}},
  639. +
  640. +{SMBwriteBmpx,"SMBwriteBmpx",0,
  641. +{"Handle=[d]\nTotCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[d]\nDataOff=[d]\n",NULL,
  642. +"Remaining=[d]\n",NULL,NULL}},
  643. +
  644. +{SMBwriteBs,"SMBwriteBs",0,
  645. +   {"Handle=[d]\nTotCount=[d]\nOffset=[D]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\n",NULL,
  646. +    "Count=[d]\n",NULL,NULL}},
  647. +
  648. +{SMBsetattrE,"SMBsetattrE",0,
  649. +   {"Handle=[d]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]",NULL,
  650. +      NULL,NULL,NULL}},
  651. +
  652. +{SMBgetattrE,"SMBgetattrE",0,
  653. +{"Handle=[d]\n",NULL,
  654. + "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[D]\nAllocSize=[D]\nAttribute=[A]\n",NULL,NULL}},
  655. +
  656. +{SMBtranss,"SMBtranss",0,DEFDESCRIPT},
  657. +{SMBioctls,"SMBioctls",0,DEFDESCRIPT},
  658. +
  659. +{SMBcopy,"SMBcopy",0,
  660. +   {"TreeID2=[d]\nOFun=[w]\nFlags=[w]\n","Path=[S]\nNewPath=[S]\n",
  661. +    "CopyCount=[d]\n","|ErrStr=[S]\n",NULL}},
  662. +
  663. +{SMBmove,"SMBmove",0,
  664. +   {"TreeID2=[d]\nOFun=[w]\nFlags=[w]\n","Path=[S]\nNewPath=[S]\n",
  665. +    "MoveCount=[d]\n","|ErrStr=[S]\n",NULL}},
  666. +
  667. +{SMBopenX,"SMBopenX",FLG_CHAIN,
  668. +{"Com2=[w]\nOff2=[d]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[D]\nTimeOut=[D]\nRes=[W]\n","Path=[S]\n",
  669. +"Com2=[w]\nOff2=[d]\nHandle=[d]\nAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nFileID=[W]\nRes=[w]\n",NULL,NULL}},
  670. +
  671. +{SMBreadX,"SMBreadX",FLG_CHAIN,
  672. +{"Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nCountLeft=[d]\n",NULL,
  673. +"Com2=[w]\nOff2=[d]\nRemaining=[d]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\nRes=([w,w,w,w])\n",NULL,NULL}},
  674. +
  675. +{SMBwriteX,"SMBwriteX",FLG_CHAIN,
  676. +{"Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[d]\nRes=[w]\nDataSize=[d]\nDataOff=[d]\n",NULL,
  677. +"Com2=[w]\nOff2=[d]\nCount=[d]\nRemaining=[d]\nRes=[W]\n",NULL,NULL}},
  678. +
  679. +{SMBlockingX,"SMBlockingX",FLG_CHAIN,
  680. +{"Com2=[w]\nOff2=[d]\nHandle=[d]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[d]\nLockCount=[d]\n",
  681. +"*Process=[d]\nOffset=[D]\nLength=[D]\n",
  682. +"Com2=[w]\nOff2=[d]\n"}},
  683. +
  684. +{SMBffirst,"SMBffirst",0,
  685. +{"Count=[d]\nAttrib=[A]\n","Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
  686. +"Count=[d]\n","BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",NULL}},
  687. +
  688. +{SMBfunique,"SMBfunique",0,
  689. +{"Count=[d]\nAttrib=[A]\n","Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
  690. +"Count=[d]\n","BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",NULL}},
  691. +
  692. +{SMBfclose,"SMBfclose",0,
  693. +{"Count=[d]\nAttrib=[A]\n","Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
  694. +"Count=[d]\n","BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",NULL}},
  695. +
  696. +{SMBfindnclose, "SMBfindnclose", 0,
  697. +   {"Handle=[d]\n",NULL,NULL,NULL,NULL}},
  698. +
  699. +{SMBfindclose, "SMBfindclose", 0,
  700. +   {"Handle=[d]\n",NULL,NULL,NULL,NULL}},
  701. +
  702. +{SMBsends,"SMBsends",0,
  703. +   {NULL,"Source=[Z]\nDest=[Z]\n",NULL,NULL,NULL}},
  704. +
  705. +{SMBsendstrt,"SMBsendstrt",0,
  706. +   {NULL,"Source=[Z]\nDest=[Z]\n","GroupID=[d]\n",NULL,NULL}},
  707. +   
  708. +{SMBsendend,"SMBsendend",0,
  709. +   {"GroupID=[d]\n",NULL,NULL,NULL,NULL}},
  710. +
  711. +{SMBsendtxt,"SMBsendtxt",0,
  712. +   {"GroupID=[d]\n",NULL,NULL,NULL,NULL}},
  713. +
  714. +{SMBsendb,"SMBsendb",0,
  715. +   {NULL,"Source=[Z]\nDest=[Z]\n",NULL,NULL,NULL}},
  716. +
  717. +{SMBfwdname,"SMBfwdname",0,DEFDESCRIPT},
  718. +{SMBcancelf,"SMBcancelf",0,DEFDESCRIPT},
  719. +{SMBgetmac,"SMBgetmac",0,DEFDESCRIPT},
  720. +
  721. +{SMBnegprot,"SMBnegprot",0,
  722. +   {NULL,NULL,NULL,NULL,print_negprot}},
  723. +
  724. +{SMBsesssetupX,"SMBsesssetupX",FLG_CHAIN,
  725. +   {NULL,NULL,NULL,NULL,print_sesssetup}},
  726. +
  727. +{SMBtconX,"SMBtconX",FLG_CHAIN,
  728. +{"Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n",NULL,
  729. + "Com2=[w]\nOff2=[d]\n","ServiceType=[S]\n",NULL}},
  730. +
  731. +{SMBtrans2, "SMBtrans2",0,{NULL,NULL,NULL,NULL,print_trans2}},
  732. +
  733. +{SMBtranss2, "SMBtranss2", 0,DEFDESCRIPT},
  734. +{SMBctemp,"SMBctemp",0,DEFDESCRIPT},
  735. +{SMBreadBs,"SMBreadBs",0,DEFDESCRIPT},
  736. +{SMBtrans,"SMBtrans",0,{NULL,NULL,NULL,NULL,print_trans}},
  737. +
  738. +{-1,NULL,0,DEFDESCRIPT}};
  739. +
  740. +/*******************************************************************
  741. +print a SMB message
  742. +********************************************************************/
  743. +void print_smb(uchar *buf,uchar *maxbuf)
  744. +{
  745. +  int command;
  746. +  uchar *words, *data;
  747. +  struct smbfns *fn;
  748. +  char *fmt_smbheader = 
  749. +"[P4]SMB Command   =  [B]\nError class   =  [BP1]\nError code    =  [d]\nFlags1        =  [B]\nFlags2        =  [B][P13]\nTree ID       =  [d]\nProc ID       =  [d]\nUID           =  [d]\nMID           =  [d]\nWord Count    =  [b]\n";
  750. +
  751. +  request = (CVAL(buf,9)&0x80)?0:1;
  752. +
  753. +  command = CVAL(buf,4);
  754. +
  755. +  fn = smbfind(command,smb_fns);
  756. +
  757. +  printf("\nSMB PACKET: %s (%s)\n",fn->name,request?"REQUEST":"REPLY");
  758. +
  759. +  /* print out the header */
  760. +  fdata(buf,fmt_smbheader,buf+33);
  761. +
  762. +  if (CVAL(buf,5)) {
  763. +    int class = CVAL(buf,5);
  764. +    int num = SVAL(buf,6);
  765. +    printf("SMBError = %s\n",smb_errstr(class,num));
  766. +  }
  767. +
  768. +  words = buf+32;
  769. +  data = words + 1 + CVAL(words,0)*2;
  770. +
  771. +
  772. +  while (words && data)
  773. +    {
  774. +      char *f1,*f2;
  775. +      int wct = CVAL(words,0);
  776. +
  777. +      if (request) {
  778. +    f1 = fn->descript.req_f1;
  779. +    f2 = fn->descript.req_f2;
  780. +      } else {
  781. +    f1 = fn->descript.rep_f1;
  782. +    f2 = fn->descript.rep_f2;
  783. +      }
  784. +
  785. +      if (fn->descript.fn) {
  786. +    fn->descript.fn(words,data,buf,maxbuf);
  787. +      } else {
  788. +    if (f1) {
  789. +      printf("smbvwv[]=\n");
  790. +      fdata(words+1,f1,words + 1 + wct*2);
  791. +    } else if (wct) {
  792. +      int i;
  793. +      int v;
  794. +      printf("smbvwv[]=\n");
  795. +      for (i=0;i<wct;i++) {
  796. +        v = SVAL(words+1,2*i);
  797. +        printf("smb_vwv[%d]=%d (0x%X)\n",i,v,v);
  798. +      }
  799. +    }
  800. +    
  801. +    if (f2) {
  802. +      printf("smbbuf[]=\n");
  803. +      fdata(data+2,f2,maxbuf);
  804. +    } else {
  805. +      int bcc = SVAL(data,0);
  806. +      printf("smb_bcc=%d\n",bcc);
  807. +      if (bcc>0) {
  808. +        printf("smb_buf[]=\n");
  809. +        print_data(data+2,MIN(bcc,PTR_DIFF(maxbuf,data+2)));
  810. +      }
  811. +    }
  812. +      }
  813. +
  814. +      if ((fn->flags & FLG_CHAIN) && CVAL(words,0) && SVAL(words,1)!=0xFF) {
  815. +    command = SVAL(words,1);
  816. +    words = buf + SVAL(words,3);
  817. +    data = words + 1 + CVAL(words,0)*2;
  818. +
  819. +    fn = smbfind(command,smb_fns);
  820. +
  821. +    printf("\nSMB PACKET: %s (%s) (CHAINED)\n",fn->name,request?"REQUEST":"REPLY");
  822. +      } else {
  823. +    words = data = NULL;
  824. +      }
  825. +    }
  826. +
  827. +  printf("\n");  
  828. +}
  829. +
  830. +
  831. +/*
  832. +   print a NBT packet received across tcp on port 139
  833. +*/
  834. +void nbt_tcp_print(uchar *data,uchar *maxbuf)
  835. +{
  836. +  int flags = CVAL(data,0);
  837. +  int nbt_len = RSVAL(data,2);
  838. +  startbuf = data;
  839. +  if (maxbuf <= data) return;
  840. +
  841. +  printf("\n>>> NBT Packet\n");
  842. +
  843. +  switch (flags) {
  844. +  case 0:    
  845. +    data = fdata(data,"NBT Session Packet\nFlags=[rw]\nLength=[rd]\n",data+4);
  846. +    if (memcmp(data,"\377SMB",4)==0) {
  847. +      if (nbt_len>PTR_DIFF(maxbuf,data))
  848. +    printf("WARNING: Short packet. Try increasing the snap length (%d)\n",
  849. +           PTR_DIFF(maxbuf,data));
  850. +      print_smb(data,maxbuf>data+nbt_len?data+nbt_len:maxbuf);
  851. +    } else {
  852. +      printf("Session packet:(raw data?)\n");
  853. +    }
  854. +    break;
  855. +
  856. +  case 0x81:
  857. +    data = fdata(data,"NBT Session Request\nFlags=[rW]\nDestination=[n1]\nSource=[n1]\n",maxbuf);
  858. +    break;
  859. +
  860. +  case 0x82:
  861. +    data = fdata(data,"NBT Session Granted\nFlags=[rW]\n",maxbuf);
  862. +    break;
  863. +
  864. +  case 0x83:
  865. +    {
  866. +      int ecode = CVAL(data,4);
  867. +      data = fdata(data,"NBT SessionReject\nFlags=[rW]\nReason=[B]\n",maxbuf);
  868. +      switch (ecode) {
  869. +      case 0x80: 
  870. +    printf("Not listening on called name\n"); 
  871. +    break;
  872. +      case 0x81: 
  873. +    printf("Not listening for calling name\n"); 
  874. +    break;
  875. +      case 0x82: 
  876. +    printf("Called name not present\n"); 
  877. +    break;
  878. +      case 0x83: 
  879. +    printf("Called name present, but insufficient resources\n"); 
  880. +    break;
  881. +      default:
  882. +    printf("Unspecified error 0x%X\n",ecode); 
  883. +    break;      
  884. +      }
  885. +    }
  886. +    break;
  887. +
  888. +  case 0x85:
  889. +    data = fdata(data,"NBT Session Keepalive\nFlags=[rW]\n",maxbuf);
  890. +    break;
  891. +
  892. +  default:
  893. +    data = fdata(data,"NBT - Unknown packet type\nType=[rW]\n",maxbuf);
  894. +  }
  895. +  printf("\n");
  896. +  fflush(stdout);
  897. +}
  898. +
  899. +
  900. +/*
  901. +   print a NBT packet received across udp on port 137
  902. +*/
  903. +void nbt_udp137_print(uchar *data,uchar *maxbuf)
  904. +{
  905. +  int name_trn_id = RSVAL(data,0);
  906. +  int response = (CVAL(data,2)>>7);
  907. +  int opcode = (CVAL(data,2) >> 3) & 0xF;
  908. +  int nm_flags = ((CVAL(data,2) & 0x7) << 4) + (CVAL(data,3)>>4);
  909. +  int rcode = CVAL(data,3) & 0xF;
  910. +  int qdcount = RSVAL(data,4);
  911. +  int ancount = RSVAL(data,6);
  912. +  int nscount = RSVAL(data,8);
  913. +  int arcount = RSVAL(data,10);
  914. +  char des[1024];
  915. +  char *opcodestr="OPUNKNOWN";  
  916. +  char *p;
  917. +
  918. +  startbuf = data;
  919. +
  920. +  if (maxbuf <= data) return;
  921. +
  922. +  strcpy(des,"\n>>> NBT UDP PACKET(137): ");
  923. +
  924. +  switch (opcode) {
  925. +  case 0: opcodestr = "QUERY"; break;
  926. +  case 5: opcodestr = "REGISTRATION"; break;
  927. +  case 6: opcodestr = "RELEASE"; break;
  928. +  case 7: opcodestr = "WACK"; break;
  929. +  case 8: opcodestr = "REFRESH(8)"; break;
  930. +  case 9: opcodestr = "REFRESH"; break;
  931. +  }
  932. +  strcat(des,opcodestr);
  933. +  if (response) {
  934. +    if (rcode)
  935. +      strcat(des,"; NEGATIVE");
  936. +    else
  937. +      strcat(des,"; POSITIVE");
  938. +  }
  939. +    
  940. +  if (response) 
  941. +    strcat(des,"; RESPONSE");
  942. +  else
  943. +    strcat(des,"; REQUEST");
  944. +
  945. +  if (nm_flags&1)
  946. +    strcat(des,"; BROADCAST");
  947. +  else
  948. +    strcat(des,"; UNICAST");
  949. +  
  950. +  printf("%s\nTrnID=0x%X\nOpCode=%d\nNmFlags=0x%X\nRcode=%d\nQueryCount=%d\nAnswerCount=%d\nAuthorityCount=%d\nAddressRecCount=%d\n",
  951. +     des,name_trn_id,opcode,nm_flags,rcode,qdcount,ancount,nscount,arcount);
  952. +
  953. +  p = data + 12;
  954. +
  955. +  {
  956. +    int total = ancount+nscount+arcount;
  957. +    int i;
  958. +
  959. +    if (qdcount>100 || total>100) {
  960. +      printf("Corrupt packet??\n");
  961. +      return;
  962. +    }
  963. +
  964. +    if (qdcount) {
  965. +      printf("QuestionRecords:\n");
  966. +      for (i=0;i<qdcount;i++)
  967. +    p = fdata(p,"|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#",maxbuf);
  968. +    }
  969. +
  970. +    if (total) {
  971. +      printf("\nResourceRecords:\n");
  972. +      for (i=0;i<total;i++) {      
  973. +    int rdlen;
  974. +    int restype;
  975. +    p = fdata(p,"Name=[n1]\n#",maxbuf);
  976. +    restype = RSVAL(p,0);
  977. +    p = fdata(p,"ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n",p+8);
  978. +    rdlen = RSVAL(p,0);
  979. +    printf("ResourceLength=%d\nResourceData=\n",rdlen);
  980. +    p += 2;
  981. +    if (rdlen == 6) {
  982. +      p = fdata(p,"AddrType=[rw]\nAddress=[b.b.b.b]\n",p+rdlen);
  983. +    } else {
  984. +      if (restype == 0x21) {
  985. +        int numnames = CVAL(p,0);
  986. +        p = fdata(p,"NumNames=[B]\n",p+1);
  987. +        while (numnames--) {
  988. +          char flags[128]="";
  989. +          p = fdata(p,"Name=[n2]\t#",maxbuf);
  990. +          if (p[0] & 0x80) strcat(flags,"<GROUP> ");
  991. +          if (p[0] & 0x60 == 0) strcat(flags,"B ");
  992. +          if (p[0] & 0x60 == 1) strcat(flags,"P ");
  993. +          if (p[0] & 0x60 == 2) strcat(flags,"M ");
  994. +          if (p[0] & 0x60 == 3) strcat(flags,"_ ");
  995. +          if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
  996. +          if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
  997. +          if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
  998. +          if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
  999. +          printf("%s\n",flags);
  1000. +          p += 2;
  1001. +        }
  1002. +      } else {
  1003. +        print_data(p,rdlen);
  1004. +        p += rdlen;
  1005. +      }
  1006. +    }
  1007. +      }
  1008. +    }
  1009. +  }
  1010. +
  1011. +  if ((uchar*)p < maxbuf) {
  1012. +    fdata(p,"AdditionalData:\n",maxbuf);    
  1013. +  }      
  1014. +  
  1015. +  printf("\n");
  1016. +  fflush(stdout);
  1017. +}
  1018. +
  1019. +
  1020. +
  1021. +/*
  1022. +   print a NBT packet received across udp on port 138
  1023. +*/
  1024. +void nbt_udp138_print(uchar *data,uchar *maxbuf)
  1025. +{
  1026. +  startbuf = data;
  1027. +  if (maxbuf <= data) return;
  1028. +
  1029. +  data = fdata(data,"\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[rd] Length=[rd] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#",maxbuf);
  1030. +
  1031. +  print_smb(data,maxbuf);
  1032. +  
  1033. +  printf("\n");
  1034. +  fflush(stdout);
  1035. +}
  1036. +
  1037. +
  1038. +
  1039. +/*
  1040. +   print netbeui frames 
  1041. +*/
  1042. +void netbeui_print(uchar *data,uchar *maxbuf)
  1043. +{
  1044. +  int len = SVAL(data,1);
  1045. +  int command = CVAL(data,5);
  1046. +  uchar *data2 = data + 1 + len;
  1047. +
  1048. +  startbuf = data;
  1049. +
  1050. +  data = fdata(data,"\n>>> NetBeui Packet\nType=[B] Length=[d] Signature=[w] Command=[B]\n#",maxbuf);
  1051. +
  1052. +  switch (command) {
  1053. +  case 0xA: 
  1054. +    data = fdata(data,"NameQuery:[P1]\nSessionNumber=[B]\nNameType=[B][P2]\nResponseCorrelator=[w]\nDestination=[n2]\nSource=[n2]\n",data2);
  1055. +    break;
  1056. +
  1057. +  case 0x8:
  1058. +    data = fdata(data,"NetbiosDataGram:[P7]\nDestination=[n2]\nSource=[n2]\n",data2);
  1059. +    break;
  1060. +
  1061. +  case 0xE:
  1062. +    data = fdata(data,"NameRecognise:\n[P1]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nDestination=[n2]\nSource=[n2]\n",data2);
  1063. +    break;
  1064. +
  1065. +  case 0x19:
  1066. +    data = fdata(data,"SessionInitialise:\nData1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",data2);
  1067. +    break;
  1068. +
  1069. +  case 0x17:
  1070. +    data = fdata(data,"SessionConfirm:\nData1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",data2);
  1071. +    break;
  1072. +
  1073. +  case 0x16:
  1074. +    data = fdata(data,"NetbiosDataOnlyLast:\nFlags=[{|NO_ACK|PIGGYBACK_ACK_ALLOWED|PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",data2);
  1075. +    break;
  1076. +
  1077. +  case 0x14:
  1078. +    data = fdata(data,"NetbiosDataAck:\n[P3]TransmitCorrelator=[w][P2]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",data2);
  1079. +    break;
  1080. +
  1081. +  case 0x18:
  1082. +    data = fdata(data,"SessionEnd:\n[P1]Data2=[w][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n",data2);
  1083. +    break;
  1084. +
  1085. +  default:
  1086. +    data = fdata(data,"Unknown Netbios Command ",data2);
  1087. +    break;
  1088. +  }
  1089. +
  1090. +  if (memcmp(data2,"\377SMB",4)==0) {
  1091. +    print_smb(data2,maxbuf);
  1092. +  } else {
  1093. +    fdata(data2,"Extra ",maxbuf);
  1094. +  }
  1095. +
  1096. +  printf("\n");
  1097. +}
  1098. +
  1099. +
  1100. +/*
  1101. +   print IPX-Netbios frames 
  1102. +*/
  1103. +void ipx_netbios_print(uchar *data,uchar *maxbuf)
  1104. +{
  1105. +  /* this is a hack till I work out how to parse the rest of the IPX stuff */
  1106. +  int i;
  1107. +  startbuf = data;
  1108. +  for (i=0;i<128;i++)
  1109. +    if (memcmp(&data[i],"\377SMB",4)==0) {
  1110. +      fdata(data,"\n>>> IPX transport ",&data[i]);
  1111. +      print_smb(&data[i],maxbuf);
  1112. +      printf("\n");
  1113. +      fflush(stdout);
  1114. +      break;
  1115. +    }
  1116. +  if (i==128)
  1117. +    fdata(data,"\n>>> Unknown IPX ",maxbuf);
  1118. +}
  1119. diff -u --new-file orig/print-tcp.c ./print-tcp.c
  1120. --- orig/print-tcp.c    Tue Jun 20 23:00:00 1995
  1121. +++ ./print-tcp.c    Thu Jun 22 14:37:17 1995
  1122. @@ -275,11 +275,15 @@
  1123.      }
  1124.  
  1125.      data = ((char *)tp+(tp->th_off *4));
  1126. -    if ( Dflag && length > 0 ) {
  1127. -        printf("\n\tData (%d): ", length);
  1128. -        fflush(stdout);
  1129. -        asc_write(1, data, 
  1130. -            ((length > (snapend-data)) ? (snapend-data) : length));
  1131. +    if (sport==139 || dport==139) {
  1132. +      nbt_tcp_print(data,data+length>snapend?snapend:data+length);
  1133. +    } else {
  1134. +      if ( Dflag && length > 0 ) {
  1135. +        printf("\n\tData (%d): ", length);
  1136. +        fflush(stdout);
  1137. +        asc_write(1, data, 
  1138. +              ((length > (snapend-data)) ? (snapend-data) : length));
  1139. +      }
  1140.      }
  1141.  }
  1142.  
  1143. diff -u --new-file orig/print-udp.c ./print-udp.c
  1144. --- orig/print-udp.c    Tue Jun 20 23:00:00 1995
  1145. +++ ./print-udp.c    Thu Jun 22 00:50:04 1995
  1146. @@ -249,6 +249,14 @@
  1147.              ntp_print((const u_char *)(up + 1), length);
  1148.          else if (dport == 3456)
  1149.              vat_print((const void *)(up + 1), length, up);
  1150. +        else if (ISPORT(137)) {
  1151. +          unsigned char *data = (unsigned char *)(up + 1);
  1152. +          nbt_udp137_print(data,data+length>snapend?snapend:data+length);
  1153. +        }
  1154. +        else if (ISPORT(138)) {
  1155. +          unsigned char *data = (unsigned char *)(up + 1);
  1156. +          nbt_udp138_print(data,data+length>snapend?snapend:data+length);
  1157. +        }
  1158.          /*
  1159.           * Kludge in test for whiteboard packets.
  1160.           */
  1161. diff -u --new-file orig/smb.h ./smb.h
  1162. --- orig/smb.h    Thu Jan  1 10:00:00 1970
  1163. +++ ./smb.h    Wed Jun 21 23:54:35 1995
  1164. @@ -0,0 +1,158 @@
  1165. +/* 
  1166. +   Copyright (C) Andrew Tridgell 1995
  1167. +   
  1168. +   This program is free software; you can redistribute it and/or modify
  1169. +   it under the terms of the GNU General Public License as published by
  1170. +   the Free Software Foundation; either version 2 of the License, or
  1171. +   (at your option) any later version.
  1172. +   
  1173. +   This program is distributed in the hope that it will be useful,
  1174. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1175. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1176. +   GNU General Public License for more details.
  1177. +   
  1178. +   You should have received a copy of the GNU General Public License
  1179. +   along with this program; if not, write to the Free Software
  1180. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1181. +*/
  1182. +
  1183. +#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
  1184. +#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
  1185. +#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
  1186. +
  1187. +#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
  1188. +#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
  1189. +#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
  1190. +#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
  1191. +#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
  1192. +#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
  1193. +#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
  1194. +#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
  1195. +#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
  1196. +#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
  1197. +
  1198. +/* now the reverse routines - these are used in nmb packets (mostly) */
  1199. +#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
  1200. +#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
  1201. +
  1202. +#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
  1203. +#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
  1204. +#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
  1205. +#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
  1206. +
  1207. +#define uint16 unsigned short
  1208. +#define uint32 unsigned int
  1209. +#ifndef uchar
  1210. +#define uchar unsigned char
  1211. +#endif
  1212. +
  1213. +#ifndef MIN
  1214. +#define MIN(a,b) ((a)<(b)?(a):(b))
  1215. +#endif
  1216. +
  1217. +/* the complete */
  1218. +#define SMBmkdir      0x00   /* create directory */
  1219. +#define SMBrmdir      0x01   /* delete directory */
  1220. +#define SMBopen       0x02   /* open file */
  1221. +#define SMBcreate     0x03   /* create file */
  1222. +#define SMBclose      0x04   /* close file */
  1223. +#define SMBflush      0x05   /* flush file */
  1224. +#define SMBunlink     0x06   /* delete file */
  1225. +#define SMBmv         0x07   /* rename file */
  1226. +#define SMBgetatr     0x08   /* get file attributes */
  1227. +#define SMBsetatr     0x09   /* set file attributes */
  1228. +#define SMBread       0x0A   /* read from file */
  1229. +#define SMBwrite      0x0B   /* write to file */
  1230. +#define SMBlock       0x0C   /* lock byte range */
  1231. +#define SMBunlock     0x0D   /* unlock byte range */
  1232. +#define SMBctemp      0x0E   /* create temporary file */
  1233. +#define SMBmknew      0x0F   /* make new file */
  1234. +#define SMBchkpth     0x10   /* check directory path */
  1235. +#define SMBexit       0x11   /* process exit */
  1236. +#define SMBlseek      0x12   /* seek */
  1237. +#define SMBtcon       0x70   /* tree connect */
  1238. +#define SMBtconX      0x75   /* tree connect and X*/
  1239. +#define SMBtdis       0x71   /* tree disconnect */
  1240. +#define SMBnegprot    0x72   /* negotiate protocol */
  1241. +#define SMBdskattr    0x80   /* get disk attributes */
  1242. +#define SMBsearch     0x81   /* search directory */
  1243. +#define SMBsplopen    0xC0   /* open print spool file */
  1244. +#define SMBsplwr      0xC1   /* write to print spool file */
  1245. +#define SMBsplclose   0xC2   /* close print spool file */
  1246. +#define SMBsplretq    0xC3   /* return print queue */
  1247. +#define SMBsends      0xD0   /* send single block message */
  1248. +#define SMBsendb      0xD1   /* send broadcast message */
  1249. +#define SMBfwdname    0xD2   /* forward user name */
  1250. +#define SMBcancelf    0xD3   /* cancel forward */
  1251. +#define SMBgetmac     0xD4   /* get machine name */
  1252. +#define SMBsendstrt   0xD5   /* send start of multi-block message */
  1253. +#define SMBsendend    0xD6   /* send end of multi-block message */
  1254. +#define SMBsendtxt    0xD7   /* send text of multi-block message */
  1255. +
  1256. +/* Core+ protocol */
  1257. +#define SMBlockread      0x13   /* Lock a range and read */
  1258. +#define SMBwriteunlock 0x14 /* Unlock a range then write */
  1259. +#define SMBreadbraw   0x1a  /* read a block of data with no smb header */
  1260. +#define SMBwritebraw  0x1d  /* write a block of data with no smb header */
  1261. +#define SMBwritec     0x20  /* secondary write request */
  1262. +#define SMBwriteclose 0x2c  /* write a file then close it */
  1263. +
  1264. +/* dos extended protocol */
  1265. +#define SMBreadBraw      0x1A   /* read block raw */
  1266. +#define SMBreadBmpx      0x1B   /* read block multiplexed */
  1267. +#define SMBreadBs        0x1C   /* read block (secondary response) */
  1268. +#define SMBwriteBraw     0x1D   /* write block raw */
  1269. +#define SMBwriteBmpx     0x1E   /* write block multiplexed */
  1270. +#define SMBwriteBs       0x1F   /* write block (secondary request) */
  1271. +#define SMBwriteC        0x20   /* write complete response */
  1272. +#define SMBsetattrE      0x22   /* set file attributes expanded */
  1273. +#define SMBgetattrE      0x23   /* get file attributes expanded */
  1274. +#define SMBlockingX      0x24   /* lock/unlock byte ranges and X */
  1275. +#define SMBtrans         0x25   /* transaction - name, bytes in/out */
  1276. +#define SMBtranss        0x26   /* transaction (secondary request/response) */
  1277. +#define SMBioctl         0x27   /* IOCTL */
  1278. +#define SMBioctls        0x28   /* IOCTL  (secondary request/response) */
  1279. +#define SMBcopy          0x29   /* copy */
  1280. +#define SMBmove          0x2A   /* move */
  1281. +#define SMBecho          0x2B   /* echo */
  1282. +#define SMBopenX         0x2D   /* open and X */
  1283. +#define SMBreadX         0x2E   /* read and X */
  1284. +#define SMBwriteX        0x2F   /* write and X */
  1285. +#define SMBsesssetupX    0x73   /* Session Set Up & X (including User Logon) */
  1286. +#define SMBtconX         0x75   /* tree connect and X */
  1287. +#define SMBffirst        0x82   /* find first */
  1288. +#define SMBfunique       0x83   /* find unique */
  1289. +#define SMBfclose        0x84   /* find close */
  1290. +#define SMBinvalid       0xFE   /* invalid command */
  1291. +
  1292. +/* Extended 2.0 protocol */
  1293. +#define SMBtrans2        0x32   /* TRANS2 protocol set */
  1294. +#define SMBtranss2       0x33   /* TRANS2 protocol set, secondary command */
  1295. +#define SMBfindclose     0x34   /* Terminate a TRANSACT2_FINDFIRST */
  1296. +#define SMBfindnclose    0x35   /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
  1297. +#define SMBulogoffX      0x74   /* user logoff */
  1298. +
  1299. +/* pathworks special */
  1300. +#define pSETDIR '\377'
  1301. +
  1302. +
  1303. +/* these are the TRANS2 sub commands */
  1304. +#define TRANSACT2_OPEN          0
  1305. +#define TRANSACT2_FINDFIRST     1
  1306. +#define TRANSACT2_FINDNEXT      2
  1307. +#define TRANSACT2_QFSINFO       3
  1308. +#define TRANSACT2_SETFSINFO     4
  1309. +#define TRANSACT2_QPATHINFO     5
  1310. +#define TRANSACT2_SETPATHINFO   6
  1311. +#define TRANSACT2_QFILEINFO     7
  1312. +#define TRANSACT2_SETFILEINFO   8
  1313. +#define TRANSACT2_FSCTL         9
  1314. +#define TRANSACT2_IOCTL           10
  1315. +#define TRANSACT2_FINDNOTIFYFIRST 11
  1316. +#define TRANSACT2_FINDNOTIFYNEXT  12
  1317. +#define TRANSACT2_MKDIR           13
  1318. +
  1319. +#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
  1320. +
  1321. +/* some protos */
  1322. +uchar *fdata(uchar *buf,char *fmt,uchar *maxbuf);
  1323. diff -u --new-file orig/smbutil.c ./smbutil.c
  1324. --- orig/smbutil.c    Thu Jan  1 10:00:00 1970
  1325. +++ ./smbutil.c    Thu Jun 29 09:01:56 1995
  1326. @@ -0,0 +1,643 @@
  1327. +#include <sys/param.h>
  1328. +#include <sys/time.h>
  1329. +#include <sys/types.h>
  1330. +#include <sys/socket.h>
  1331. +
  1332. +#include <net/if.h>
  1333. +
  1334. +#include <netinet/in.h>
  1335. +#include <netinet/if_ether.h>
  1336. +
  1337. +#include <ctype.h>
  1338. +#include <stdio.h>
  1339. +#include <string.h>
  1340. +
  1341. +#include "smb.h"
  1342. +
  1343. +extern uchar *startbuf;
  1344. +
  1345. +/*******************************************************************
  1346. +  interpret a 32 bit dos packed date/time to some parameters
  1347. +********************************************************************/
  1348. +static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second)
  1349. +{
  1350. +  uint32 p0,p1,p2,p3;
  1351. +
  1352. +  p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; 
  1353. +  p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF;
  1354. +
  1355. +  *second = 2*(p0 & 0x1F);
  1356. +  *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3);
  1357. +  *hour = (p1>>3)&0xFF;
  1358. +  *day = (p2&0x1F);
  1359. +  *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1;
  1360. +  *year = ((p3>>1)&0xFF) + 80;
  1361. +}
  1362. +
  1363. +/*******************************************************************
  1364. +  create a unix date from a dos date
  1365. +********************************************************************/
  1366. +time_t make_unix_date(void *date_ptr)
  1367. +{
  1368. +  uint32 dos_date=0;
  1369. +  struct tm t;
  1370. +
  1371. +  dos_date = IVAL(date_ptr,0);
  1372. +
  1373. +  if (dos_date == 0) return(0);
  1374. +  
  1375. +  interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon,
  1376. +             &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec);
  1377. +  t.tm_wday = 1;
  1378. +  t.tm_yday = 1;
  1379. +  t.tm_isdst = 0;
  1380. +
  1381. +  return (mktime(&t));
  1382. +}
  1383. +
  1384. +/*******************************************************************
  1385. +  create a unix date from a dos date
  1386. +********************************************************************/
  1387. +time_t make_unix_date2(void *date_ptr)
  1388. +{
  1389. +  uint32 x,x2;
  1390. +
  1391. +  x = IVAL(date_ptr,0);
  1392. +  x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
  1393. +  SIVAL(&x,0,x2);
  1394. +
  1395. +  return(make_unix_date((void *)&x));
  1396. +}
  1397. +
  1398. +/****************************************************************************
  1399. +interpret an 8 byte "filetime" structure to a time_t
  1400. +It's originally in "100ns units since jan 1st 1601"
  1401. +****************************************************************************/
  1402. +time_t interpret_long_date(char *p)
  1403. +{
  1404. +  double d;
  1405. +  time_t ret;
  1406. +
  1407. +  /* this gives us seconds since jan 1st 1601 (approx) */
  1408. +  d = (IVAL(p,4)*256.0 + CVAL(p,3)) * (1.0e-7 * (1<<24));
  1409. +  /* now adjust by 369 years to make the secs since 1970 */
  1410. +  d -= 369.0*365.25*24*60*60;
  1411. +
  1412. +  /* and a fudge factor as we got it wrong by a few days */
  1413. +  d += (3*24*60*60 + 6*60*60 + 2);
  1414. +
  1415. +  if (d<0)
  1416. +    return(0);
  1417. +
  1418. +  ret = (time_t)d;
  1419. +
  1420. +  return(ret);
  1421. +}
  1422. +
  1423. +
  1424. +/****************************************************************************
  1425. +interpret the weird netbios "name". Return the name type
  1426. +****************************************************************************/
  1427. +static int name_interpret(char *in,char *out)
  1428. +{
  1429. +  int ret;
  1430. +  int len = (*in++) / 2;
  1431. +
  1432. +  *out=0;
  1433. +
  1434. +  if (len > 30 || len<1) return(0);
  1435. +
  1436. +  while (len--)
  1437. +    {
  1438. +      if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
  1439. +    *out = 0;
  1440. +    return(0);
  1441. +      }
  1442. +      *out = ((in[0]-'A')<<4) + (in[1]-'A');
  1443. +      in += 2;
  1444. +      out++;
  1445. +    }
  1446. +  *out = 0;
  1447. +  ret = out[-1];
  1448. +
  1449. +  /* Handle any scope names */
  1450. +  while(*in) 
  1451. +    {
  1452. +      *out++ = '.';
  1453. +      len = *in++;
  1454. +      strncpy(out, in, len);
  1455. +      out += len;
  1456. +      *out=0;
  1457. +      in += len;
  1458. +    }
  1459. +  return(ret);
  1460. +}
  1461. +
  1462. +/****************************************************************************
  1463. +find a pointer to a netbios name
  1464. +****************************************************************************/
  1465. +static char *name_ptr(char *buf,int ofs)
  1466. +{
  1467. +  unsigned char c = *(unsigned char *)(buf+ofs);
  1468. +
  1469. +  if ((c & 0xC0) == 0xC0)
  1470. +    {
  1471. +      uint16 l;
  1472. +      char p[2];
  1473. +      memcpy(p,buf+ofs,2);
  1474. +      p[0] &= ~0xC0;
  1475. +      l = RSVAL(p,0);
  1476. +      return(buf + l);
  1477. +    }
  1478. +  else
  1479. +    return(buf+ofs);
  1480. +}  
  1481. +
  1482. +/****************************************************************************
  1483. +extract a netbios name from a buf
  1484. +****************************************************************************/
  1485. +static int name_extract(char *buf,int ofs,char *name)
  1486. +{
  1487. +  char *p = name_ptr(buf,ofs);
  1488. +  int d = PTR_DIFF(p,buf+ofs);
  1489. +  strcpy(name,"");
  1490. +  return(name_interpret(p,name));
  1491. +}  
  1492. +  
  1493. +
  1494. +/****************************************************************************
  1495. +return the total storage length of a mangled name
  1496. +****************************************************************************/
  1497. +static int name_len(char *s)
  1498. +{
  1499. +  char *s0 = s;
  1500. +  unsigned char c = *(unsigned char *)s;
  1501. +  if ((c & 0xC0) == 0xC0)
  1502. +    return(2);  
  1503. +  while (*s) s += (*s)+1;
  1504. +  return(PTR_DIFF(s,s0)+1);
  1505. +}
  1506. +
  1507. +void print_asc(unsigned char *buf,int len)
  1508. +{
  1509. +  int i;
  1510. +  for (i=0;i<len;i++)
  1511. +    printf("%c",isprint(buf[i])?buf[i]:'.');
  1512. +}
  1513. +
  1514. +static char *name_type_str(int name_type)
  1515. +{
  1516. +  static char *f = NULL;
  1517. +  switch (name_type) {
  1518. +  case 0:    f = "Workstation"; break;
  1519. +  case 0x03: f = "Client?"; break;
  1520. +  case 0x20: f = "Server"; break;
  1521. +  case 0x1d: f = "Master Browser"; break;
  1522. +  case 0x1b: f = "Domain Controller"; break;
  1523. +  case 0x1e: f = "Browser Server"; break;
  1524. +  default:   f = "Unknown"; break;
  1525. +  }
  1526. +  return(f);
  1527. +}
  1528. +
  1529. +void print_data(unsigned char *buf,int len)
  1530. +{
  1531. +  int i=0;
  1532. +  if (len<=0) return;
  1533. +  printf("[%03X] ",i);
  1534. +  for (i=0;i<len;) {
  1535. +    printf("%02X ",(int)buf[i]);
  1536. +    i++;
  1537. +    if (i%8 == 0) printf(" ");
  1538. +    if (i%16 == 0) {      
  1539. +      print_asc(&buf[i-16],8); printf(" ");
  1540. +      print_asc(&buf[i-8],8); printf("\n");
  1541. +      if (i<len) printf("[%03X] ",i);
  1542. +    }
  1543. +  }
  1544. +  if (i%16) {
  1545. +    int n;
  1546. +
  1547. +    n = 16 - (i%16);
  1548. +    printf(" ");
  1549. +    if (n>8) printf(" ");
  1550. +    while (n--) printf("   ");
  1551. +
  1552. +    n = MIN(8,i%16);
  1553. +    print_asc(&buf[i-(i%16)],n); printf(" ");
  1554. +    n = (i%16) - n;
  1555. +    if (n>0) print_asc(&buf[i-n],n); 
  1556. +    printf("\n");    
  1557. +  }
  1558. +}
  1559. +
  1560. +
  1561. +static void write_bits(unsigned int val,char *fmt)
  1562. +{
  1563. +  char *p = fmt;
  1564. +  int i=0;
  1565. +
  1566. +  while ((p=strchr(fmt,'|'))) {
  1567. +    int l = PTR_DIFF(p,fmt);
  1568. +    if (l && (val & (1<<i))) 
  1569. +      printf("%.*s ",l,fmt);
  1570. +    fmt = p+1;
  1571. +    i++;
  1572. +  }
  1573. +}
  1574. +
  1575. +uchar *fdata1(uchar *buf,char *fmt,uchar *maxbuf)
  1576. +{
  1577. +  int reverse=0;
  1578. +  char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
  1579. +
  1580. +  while (*fmt && buf<maxbuf) {
  1581. +    switch (*fmt) {
  1582. +    case 'a':
  1583. +      write_bits(CVAL(buf,0),attrib_fmt);
  1584. +      buf++; fmt++;
  1585. +      break;
  1586. +
  1587. +    case 'A':
  1588. +      write_bits(SVAL(buf,0),attrib_fmt);
  1589. +      buf+=2; fmt++;
  1590. +      break;
  1591. +
  1592. +    case '{':
  1593. +      {
  1594. +    char bitfmt[128];
  1595. +    char *p = strchr(++fmt,'}');
  1596. +    int l = PTR_DIFF(p,fmt);
  1597. +    strncpy(bitfmt,fmt,l);
  1598. +    bitfmt[l]=0;
  1599. +    fmt = p+1;
  1600. +    write_bits(CVAL(buf,0),bitfmt);
  1601. +    buf++;
  1602. +    break;
  1603. +      }
  1604. +
  1605. +    case 'P':
  1606. +      {
  1607. +    int l = atoi(fmt+1);
  1608. +    buf += l;
  1609. +    fmt++;
  1610. +    while (isdigit(*fmt)) fmt++;
  1611. +    break;
  1612. +      }
  1613. +    case 'r':
  1614. +      reverse = !reverse;
  1615. +      fmt++;
  1616. +      break;
  1617. +    case 'D':
  1618. +      {
  1619. +    unsigned int x = reverse?RIVAL(buf,0):IVAL(buf,0);
  1620. +    printf("%d",x);
  1621. +    buf += 4;
  1622. +    fmt++;
  1623. +    break;
  1624. +      }
  1625. +    case 'd':
  1626. +      {
  1627. +    unsigned int x = reverse?RSVAL(buf,0):SVAL(buf,0);
  1628. +    printf("%d",x);
  1629. +    buf += 2;
  1630. +    fmt++;
  1631. +    break;
  1632. +      }
  1633. +    case 'W':
  1634. +      {
  1635. +    unsigned int x = reverse?RIVAL(buf,0):IVAL(buf,0);
  1636. +    printf("0x%X",x);
  1637. +    buf += 4;
  1638. +    fmt++;
  1639. +    break;
  1640. +      }
  1641. +    case 'w':
  1642. +      {
  1643. +    unsigned int x = reverse?RSVAL(buf,0):SVAL(buf,0);
  1644. +    printf("0x%X",x);
  1645. +    buf += 2;
  1646. +    fmt++;
  1647. +    break;
  1648. +      }
  1649. +    case 'B':
  1650. +      {
  1651. +    unsigned int x = CVAL(buf,0);
  1652. +    printf("0x%X",x);
  1653. +    buf += 1;
  1654. +    fmt++;
  1655. +    break;
  1656. +      }
  1657. +    case 'b':
  1658. +      {
  1659. +    unsigned int x = CVAL(buf,0);
  1660. +    printf("%d",x);
  1661. +    buf += 1;
  1662. +    fmt++;
  1663. +    break;
  1664. +      }
  1665. +    case 'S':
  1666. +      {    
  1667. +    printf("%.*s",PTR_DIFF(maxbuf,buf),buf);
  1668. +    buf += strlen(buf)+1;
  1669. +    fmt++;
  1670. +    break;
  1671. +      }
  1672. +    case 'Z':
  1673. +      {    
  1674. +    if (*buf != 4 && *buf != 2) 
  1675. +      printf("Error! ASCIIZ buffer of type %d (safety=%d)\n",
  1676. +         *buf,PTR_DIFF(maxbuf,buf));
  1677. +    printf("%.*s",PTR_DIFF(maxbuf,buf+1),buf+1);
  1678. +    buf += strlen(buf+1)+2;
  1679. +    fmt++;
  1680. +    break;
  1681. +      }
  1682. +    case 's':
  1683. +      {    
  1684. +    int l = atoi(fmt+1);
  1685. +    printf("%-*.*s",l,l,buf);
  1686. +    buf += l;    
  1687. +    fmt++; while (isdigit(*fmt)) fmt++;
  1688. +    break;
  1689. +      }
  1690. +    case 'h':
  1691. +      {    
  1692. +    int l = atoi(fmt+1);
  1693. +    while (l--) printf("%02x",*buf++);
  1694. +    fmt++; while (isdigit(*fmt)) fmt++;
  1695. +    break;
  1696. +      }
  1697. +    case 'n':
  1698. +      {    
  1699. +    int t = atoi(fmt+1);
  1700. +    char nbuf[255];
  1701. +    int name_type;
  1702. +    switch (t) {
  1703. +    case 1:
  1704. +      name_type = name_extract(startbuf,PTR_DIFF(buf,startbuf),nbuf);
  1705. +      buf += name_len(buf);
  1706. +      printf("%-15.15s NameType=0x%02X (%s)",
  1707. +         nbuf,name_type,name_type_str(name_type));
  1708. +      break;
  1709. +    case 2:
  1710. +      name_type = buf[15];
  1711. +      printf("%-15.15s NameType=0x%02X (%s)",
  1712. +         buf,name_type,name_type_str(name_type));
  1713. +      buf += 16;
  1714. +      break;
  1715. +    }
  1716. +    fmt++; while (isdigit(*fmt)) fmt++;
  1717. +    break;
  1718. +      }
  1719. +    case 'T':
  1720. +      {    
  1721. +    time_t t;
  1722. +    int x = IVAL(buf,0);
  1723. +    switch (atoi(fmt+1)) {
  1724. +    case 1:
  1725. +      if (x==0 || x==-1 || x==0xFFFFFFFF)
  1726. +        t = 0;
  1727. +      else
  1728. +        t = make_unix_date(buf); 
  1729. +      buf+=4;
  1730. +      break;
  1731. +    case 2:
  1732. +      if (x==0 || x==-1 || x==0xFFFFFFFF)
  1733. +        t = 0;
  1734. +      else
  1735. +        t = make_unix_date2(buf); 
  1736. +      buf+=4;
  1737. +      break;
  1738. +    case 3:
  1739. +      t = interpret_long_date(buf); 
  1740. +      buf+=8;
  1741. +      break;
  1742. +    }
  1743. +    printf("%s",t?asctime(localtime(&t)):"NULL\n");
  1744. +    fmt++; while (isdigit(*fmt)) fmt++;
  1745. +    break;
  1746. +      }
  1747. +    default:
  1748. +      putchar(*fmt);
  1749. +      fmt++;
  1750. +      break;      
  1751. +    }
  1752. +  }
  1753. +
  1754. +  if (buf>=maxbuf && *fmt)
  1755. +    printf("END OF BUFFER\n");
  1756. +
  1757. +  return(buf);
  1758. +}
  1759. +
  1760. +uchar *fdata(uchar *buf,char *fmt,uchar *maxbuf)
  1761. +{
  1762. +  static int depth=0;
  1763. +  char s[128];
  1764. +  char *p;
  1765. +
  1766. +  while (*fmt) {
  1767. +    switch (*fmt) {
  1768. +    case '*':
  1769. +      fmt++;
  1770. +      while (buf < maxbuf) {
  1771. +    uchar *buf2;
  1772. +    depth++;
  1773. +    buf2 = fdata(buf,fmt,maxbuf);
  1774. +    depth--;
  1775. +    if (buf2 == buf) return(buf);
  1776. +    buf = buf2;
  1777. +      }
  1778. +      break;
  1779. +
  1780. +    case '|':
  1781. +      fmt++;
  1782. +      if (buf>=maxbuf) return(buf);
  1783. +      break;
  1784. +
  1785. +    case '%':
  1786. +      fmt++;
  1787. +      buf=maxbuf;
  1788. +      break;
  1789. +
  1790. +    case '#':
  1791. +      fmt++;
  1792. +      return(buf);
  1793. +      break;
  1794. +
  1795. +    case '[':
  1796. +      fmt++;
  1797. +      if (buf>=maxbuf) return(buf);
  1798. +      bzero(s,sizeof(s));
  1799. +      p = strchr(fmt,']');
  1800. +      strncpy(s,fmt,p-fmt);
  1801. +      fmt = p+1;
  1802. +      buf = fdata1(buf,s,maxbuf);
  1803. +      break;
  1804. +
  1805. +    default:
  1806. +      putchar(*fmt); fmt++;
  1807. +      fflush(stdout);
  1808. +      break;
  1809. +    }
  1810. +  }
  1811. +  if (!depth && buf<maxbuf) {
  1812. +    int len = PTR_DIFF(maxbuf,buf);
  1813. +    printf("Data: (%d bytes)\n",len);
  1814. +    print_data(buf,len);
  1815. +    return(buf+len);
  1816. +  }
  1817. +  return(buf);
  1818. +}
  1819. +
  1820. +typedef struct
  1821. +{
  1822. +  char *name;
  1823. +  int code;
  1824. +  char *message;
  1825. +} err_code_struct;
  1826. +
  1827. +/* Dos Error Messages */
  1828. +static err_code_struct dos_msgs[] = {
  1829. +  {"ERRbadfunc",1,"Invalid function."},
  1830. +  {"ERRbadfile",2,"File not found."},
  1831. +  {"ERRbadpath",3,"Directory invalid."},
  1832. +  {"ERRnofids",4,"No file descriptors available"},
  1833. +  {"ERRnoaccess",5,"Access denied."},
  1834. +  {"ERRbadfid",6,"Invalid file handle."},
  1835. +  {"ERRbadmcb",7,"Memory control blocks destroyed."},
  1836. +  {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
  1837. +  {"ERRbadmem",9,"Invalid memory block address."},
  1838. +  {"ERRbadenv",10,"Invalid environment."},
  1839. +  {"ERRbadformat",11,"Invalid format."},
  1840. +  {"ERRbadaccess",12,"Invalid open mode."},
  1841. +  {"ERRbaddata",13,"Invalid data."},
  1842. +  {"ERR",14,"reserved."},
  1843. +  {"ERRbaddrive",15,"Invalid drive specified."},
  1844. +  {"ERRremcd",16,"A Delete Directory request attempted  to  remove  the  server's  current directory."},
  1845. +  {"ERRdiffdevice",17,"Not same device."},
  1846. +  {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
  1847. +  {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing  FIDs  on the file."},
  1848. +  {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an  invalid mode,  or an Unlock requested attempted to remove a lock held by another process."},
  1849. +  {"ERRfilexists",80,"The file named in a Create Directory, Make  New  File  or  Link  request already exists."},
  1850. +  {"ERRbadpipe",230,"Pipe invalid."},
  1851. +  {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
  1852. +  {"ERRpipeclosing",232,"Pipe close in progress."},
  1853. +  {"ERRnotconnected",233,"No process on other end of pipe."},
  1854. +  {"ERRmoredata",234,"There is more data to be returned."},
  1855. +  {NULL,-1,NULL}};
  1856. +
  1857. +/* Server Error Messages */
  1858. +err_code_struct server_msgs[] = {
  1859. +  {"ERRerror",1,"Non-specific error code."},
  1860. +  {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
  1861. +  {"ERRbadtype",3,"reserved."},
  1862. +  {"ERRaccess",4,"The requester does not have  the  necessary  access  rights  within  the specified  context for the requested function. The context is defined by the TID or the UID."},
  1863. +  {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
  1864. +  {"ERRinvnetname",6,"Invalid network name in tree connect."},
  1865. +  {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or  non-printer request made to printer connection."},
  1866. +  {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
  1867. +  {"ERRqtoobig",50,"Print queue full -- no space."},
  1868. +  {"ERRqeof",51,"EOF on print queue dump."},
  1869. +  {"ERRinvpfid",52,"Invalid print file FID."},
  1870. +  {"ERRsmbcmd",64,"The server did not recognize the command received."},
  1871. +  {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
  1872. +  {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid  combination of values."},
  1873. +  {"ERRreserved",68,"reserved."},
  1874. +  {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination.  The server cannot set the requested attribute."},
  1875. +  {"ERRreserved",70,"reserved."},
  1876. +  {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
  1877. +  {"ERRpaused",81,"Server is paused."},
  1878. +  {"ERRmsgoff",82,"Not receiving messages."},
  1879. +  {"ERRnoroom",83,"No room to buffer message."},
  1880. +  {"ERRrmuns",87,"Too many remote user names."},
  1881. +  {"ERRtimeout",88,"Operation timed out."},
  1882. +  {"ERRnoresource",89,"No resources currently available for request."},
  1883. +  {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
  1884. +  {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
  1885. +  {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
  1886. +  {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
  1887. +  {"ERRcontmpx",252,"Continue in MPX mode."},
  1888. +  {"ERRreserved",253,"reserved."},
  1889. +  {"ERRreserved",254,"reserved."},
  1890. +  {"ERRnosupport",0xFFFF,"Function not supported."},
  1891. +  {NULL,-1,NULL}};
  1892. +
  1893. +/* Hard Error Messages */
  1894. +err_code_struct hard_msgs[] = {
  1895. +  {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
  1896. +  {"ERRbadunit",20,"Unknown unit."},
  1897. +  {"ERRnotready",21,"Drive not ready."},
  1898. +  {"ERRbadcmd",22,"Unknown command."},
  1899. +  {"ERRdata",23,"Data error (CRC)."},
  1900. +  {"ERRbadreq",24,"Bad request structure length."},
  1901. +  {"ERRseek",25 ,"Seek error."},
  1902. +  {"ERRbadmedia",26,"Unknown media type."},
  1903. +  {"ERRbadsector",27,"Sector not found."},
  1904. +  {"ERRnopaper",28,"Printer out of paper."},
  1905. +  {"ERRwrite",29,"Write fault."},
  1906. +  {"ERRread",30,"Read fault."},
  1907. +  {"ERRgeneral",31,"General failure."},
  1908. +  {"ERRbadshare",32,"A open conflicts with an existing open."},
  1909. +  {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
  1910. +  {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
  1911. +  {"ERRFCBUnavail",35,"No FCBs are available to process request."},
  1912. +  {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
  1913. +  {NULL,-1,NULL}};
  1914. +
  1915. +
  1916. +static struct
  1917. +{
  1918. +  int code;
  1919. +  char *class;
  1920. +  err_code_struct *err_msgs;
  1921. +} err_classes[] = { 
  1922. +  {0,"SUCCESS",NULL},
  1923. +  {0x01,"ERRDOS",dos_msgs},
  1924. +  {0x02,"ERRSRV",server_msgs},
  1925. +  {0x03,"ERRHRD",hard_msgs},
  1926. +  {0x04,"ERRXOS",NULL},
  1927. +  {0xE1,"ERRRMX1",NULL},
  1928. +  {0xE2,"ERRRMX2",NULL},
  1929. +  {0xE3,"ERRRMX3",NULL},
  1930. +  {0xFF,"ERRCMD",NULL},
  1931. +  {-1,NULL,NULL}};
  1932. +
  1933. +
  1934. +/****************************************************************************
  1935. +return a SMB error string from a SMB buffer
  1936. +****************************************************************************/
  1937. +char *smb_errstr(int class,int num)
  1938. +{
  1939. +  static char ret[128];
  1940. +  int i,j;
  1941. +
  1942. +  ret[0]=0;
  1943. +
  1944. +  for (i=0;err_classes[i].class;i++)
  1945. +    if (err_classes[i].code == class)
  1946. +      {
  1947. +    if (err_classes[i].err_msgs)
  1948. +      {
  1949. +        err_code_struct *err = err_classes[i].err_msgs;
  1950. +        for (j=0;err[j].name;j++)
  1951. +          if (num == err[j].code)
  1952. +        {
  1953. +          sprintf(ret,"%s - %s (%s)",err_classes[i].class,
  1954. +              err[j].name,err[j].message);
  1955. +          return ret;
  1956. +        }
  1957. +      }
  1958. +
  1959. +    sprintf(ret,"%s - %d",err_classes[i].class,num);
  1960. +    return ret;
  1961. +      }
  1962. +  
  1963. +  sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);
  1964. +  return(ret);
  1965. +}
  1966. +
  1967. +
  1968. +
  1969. diff -u --new-file orig/tcpdump.c ./tcpdump.c
  1970. --- orig/tcpdump.c    Tue Jun 20 23:00:00 1995
  1971. +++ ./tcpdump.c    Thu Jun 29 00:38:52 1995
  1972. @@ -68,7 +68,7 @@
  1973.  
  1974.  char *program_name;
  1975.  
  1976. -int thiszone;
  1977. +int thiszone=0;
  1978.  
  1979.  SIGRET cleanup(int);
  1980.  extern void bpf_dump(struct bpf_program *, int);
  1981.